package com.jackchong.utils;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.text.TextPaint;
import android.text.style.ForegroundColorSpan;
import android.util.LruCache;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;

import androidx.annotation.IdRes;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.tabs.TabLayout;
import com.jackchong.widget.JRecyclerView;

import java.util.ArrayList;
import java.util.List;

import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;


/**
 * 作者: jack(黄冲)
 * 邮箱: 907755845@qq.com
 * create on 2018/6/19 18:41
 */

public class ViewUtils {

    public static void move(@IdRes int icon, View parent, boolean lock) {
        move(icon, parent, 0, lock);
    }

    public static void move(@IdRes int icon, View parent) {
        move(icon, parent, 0, false);
    }

    public static void move(@IdRes int icon, View parent, int page) {
        move(icon, parent, page, false);
    }

    @SuppressLint("ClickableViewAccessibility")
    public static void move(@IdRes int icon, View parent, int page, boolean lock) {
        parent.findViewById(icon).setOnTouchListener((v, event) -> {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    //存入一个PointF数组  大小为2个, 第一个为记录总的偏移量, 第二个为记录move每次移动的最新坐标
                    v.setTag(new PointF[]{new PointF(0, 0), new PointF(event.getRawX(), event.getRawY())});
                    break;
                case MotionEvent.ACTION_MOVE:
                    PointF[] pointFs = (PointF[]) v.getTag();
                    PointF point1 = pointFs[0];
                    PointF point2 = pointFs[1];
                    int dx = (int) (event.getRawX() - point2.x);
                    int dy = (int) (event.getRawY() - point2.y);

                    point1.x += Math.abs(dx);
                    point1.y += Math.abs(dy);

                    int left = v.getLeft() + dx;
                    int top = v.getTop() + dy;
                    int width = v.getWidth();
                    int height = v.getHeight();

                    //如果有ViewPage  实际的getLeft = 宽度 * 页数
                    int pageOffset = DeviceInfo.sScreenRect.width() * page;

                    int parentLeft = parent.getLeft() - pageOffset;
                    int parentRight = parent.getRight() - pageOffset - width;
                    int parentTop = parent.getTop();
                    int parentBottom = parent.getBottom() - height;

                    left = left < parentLeft ? parentLeft : left > parentRight ? parentRight : left;
                    top = top < parentTop ? parentTop : top > parentBottom ? parentBottom : top;

                    if (lock) {
                        ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) v.getLayoutParams();

                        int leftMargin = layoutParams.leftMargin += dx;
                        int bottomMargin = layoutParams.bottomMargin += -dy;

                        JLog.e("测试", String.valueOf(bottomMargin) + "  " + parent.getHeight() + "   " + (v.getHeight()) + "   " + layoutParams.topMargin);
                        layoutParams.leftMargin = leftMargin < 0 ? 0 : leftMargin > parent.getWidth() - v.getWidth() ? parent.getWidth() - v.getWidth() : leftMargin;
                        layoutParams.bottomMargin = bottomMargin < 0 ? 0 : bottomMargin > parent.getHeight() - v.getHeight() - DeviceInfo.sStatusBarHeight ? parent.getHeight() - v.getHeight() - DeviceInfo.sStatusBarHeight : bottomMargin;
                        JLog.e("测试", String.valueOf(bottomMargin));
                        v.setLayoutParams(layoutParams);
                    } else {
                        v.setLeft(left);
                        v.setTop(top);
                        v.setRight(left + width);
                        v.setBottom(top + height);
                    }

                    point2.x = event.getRawX();
                    point2.y = event.getRawY();
                    break;
                case MotionEvent.ACTION_UP:
                    //拦截了事件, 所以需要手动分发点击事件
                    PointF point = ((PointF[]) v.getTag())[0];
                    //小于这个范围算点击
                    float maxOffset = DeviceInfo.sAutoScaleX * 50;
                    if (point.x < maxOffset && point.y < maxOffset) {
                        v.performClick();
                        return true;
                    }
                    startAnim(v, lock);
                    break;
            }
            return true;
        });
    }

    private static void startAnim(View view, boolean lock) {

        int offset;
        if (view.getLeft() + view.getWidth() / 2 < DeviceInfo.sScreenRect.width() / 2) {
            offset = (int) (DeviceInfo.sAutoScaleX * 30 - view.getLeft());
        } else {
            offset = (int) (DeviceInfo.sScreenRect.width() - DeviceInfo.sAutoScaleX * 30 - view.getRight());
        }
        int left = view.getLeft();
        int right = view.getRight();

        ValueAnimator animator = ValueAnimator.ofInt(0, offset);
        animator.setDuration(500);
        animator.addUpdateListener(animation -> {
            int value = (int) animation.getAnimatedValue();

            if (lock) {
                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
                layoutParams.leftMargin = left + value;
                view.setLayoutParams(layoutParams);
            } else {
                view.setLeft(left + value);
                view.setRight(right + value);
            }
        });
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
                layoutParams.leftMargin = view.getLeft();
                layoutParams.bottomMargin = ((View) view.getParent()).getHeight() - view.getBottom();
                view.setLayoutParams(layoutParams);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator.start();
    }


    /**
     * 获取ListView头部List
     *
     * @param listView
     * @return
     */
    public static ArrayList<ListView.FixedViewInfo> getHeaderViewList(ListView listView) {
        return (ArrayList<ListView.FixedViewInfo>) ReflexUtils.getField(listView, "mHeaderViewInfos");
    }

    /**
     * 获取ListView尾部List
     *
     * @param listView
     * @return
     */
    public static ArrayList<ListView.FixedViewInfo> getFooterViewList(ListView listView) {
        return (ArrayList<ListView.FixedViewInfo>) ReflexUtils.getField(listView, "mFooterViewInfos");
    }

    public static Rect getScreenLocation(View view) {
        int[] ints = new int[2];
        view.getLocationOnScreen(ints);
        return new Rect(ints[0], ints[1], ints[0] + view.getWidth(), ints[1] + view.getHeight());
    }

    public static Rect getParentLocation(View view) {
        return new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
    }

    public static Bitmap getBitmap(View view) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        if (view.getBackground() != null) {
            view.getBackground().draw(canvas);
        }
        view.draw(canvas);
        return bitmap;
    }

    public static Bitmap getBitmap(View view, int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        if (view.getBackground() != null) {
            view.getBackground().draw(canvas);
        }
        view.draw(canvas);
        return bitmap;
    }

    /**
     * 返回两个View在屏幕上的相交区域 这个区域在 0 - 1之间. 如未相交则为0, 如A被B包含则为1
     *
     * @param v1
     * @param v2
     * @return 相交的百分比 0 - 1
     */
    public static double intersectScale(View v1, View v2) {
        Rect rect1 = getScreenLocation(v1);
        Rect rect2 = getScreenLocation(v2);

        int width = Math.min(rect1.right - rect2.left, rect2.right - rect1.left);
        int height = Math.min(rect1.bottom - rect2.top, rect2.bottom - rect1.top);


        if (width < 0 || height < 0) return 0;
        if (width * height > rect1.width() * rect1.height() || (width == 0 && height == 0)) {
            return 1;
        }
        return (width * height) * 1.0f / (rect1.width() * rect1.height());
    }


    public static float getTextCenterY(float y, TextPaint textPaint) {
        return y - (textPaint.ascent() - textPaint.baselineShift) / 2;
    }

    public static void setTabLayoutWidth(TabLayout tabLayout, int paddingLeft, int paddingRight) {
        LinearLayout mTabStrip = (LinearLayout) tabLayout.getChildAt(0);
        for (int i = 0; i < mTabStrip.getChildCount(); i++) {
            View tabView  = mTabStrip.getChildAt(i);
            TextView  mTextView = (TextView) ReflexUtils.getField(tabView, "mTextView");
            int width = 0;
            width = mTextView.getWidth();
            if (width == 0) {
                mTextView.measure(0, 0);
                width = mTextView.getMeasuredWidth();
            }
            tabView.setPadding(paddingLeft, 0, paddingRight, 0);
            LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) tabView.getLayoutParams();
            params.width = width + paddingLeft + paddingRight;
            params.leftMargin = 0;
            params.rightMargin = 0;
            tabView.setLayoutParams(params);
            tabView.invalidate();
        }

    }

    public static int getRecyclerViewScollY(JRecyclerView recyclerView) {
        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
        int position = layoutManager.findFirstVisibleItemPosition();
        View firstVisiableChildView = layoutManager.findViewByPosition(position);
        int itemHeight = firstVisiableChildView.getHeight();
        return (position) * itemHeight - firstVisiableChildView.getTop();
    }



    /**
     * time    : 2019/4/14 12:55
     * desc    : 匹配的字符串变色
     * versions: 1.0
     */
    public static CharSequence matcherSearchText(int color, String string, String ... keyWords) {
        SpannableStringBuilder builder = new SpannableStringBuilder(string);
        for (String keyWord : keyWords) {
            int indexOf = string.indexOf(keyWord);
            if (indexOf != -1) {
                builder.setSpan(new ForegroundColorSpan(color), indexOf, indexOf + keyWord.length(), SPAN_EXCLUSIVE_EXCLUSIVE);

            }
        }
        return builder;
    }

    public static void toAnchor(int index, RecyclerView recyclerView){
        LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
        layoutManager.scrollToPositionWithOffset(index, 0);
        layoutManager.setStackFromEnd(true);
    }

    public static <T> void setNewData(JRecyclerView recyclerView, List<T> list) {


    }

    public static void setNewData(JRecyclerView recyclerView, Runnable runnable) {
        if (recyclerView.isComputingLayout()){
            ThreadUtils.postDelay(50, () -> setNewData(recyclerView, runnable));
        }else {
            runnable.run();
        }
    }


    public static Bitmap shotRecyclerView(RecyclerView view) {
        RecyclerView.Adapter adapter = view.getAdapter();
        Bitmap bigBitmap = null;
        if (adapter != null) {
            int size = adapter.getItemCount();
            int height = 0;
            Paint paint = new Paint();
            int iHeight = 0;
            final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

            // Use 1/8th of the available memory for this memory cache.
            final int cacheSize = maxMemory / 8;
            LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);
            for (int i = 0; i < size; i++) {
                RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));
                adapter.onBindViewHolder(holder, i);
                holder.itemView.measure(
                        View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(),
                        holder.itemView.getMeasuredHeight());
                holder.itemView.setDrawingCacheEnabled(true);
                holder.itemView.buildDrawingCache();
                Bitmap drawingCache = holder.itemView.getDrawingCache();
                if (drawingCache != null) {

                    bitmaCache.put(String.valueOf(i), drawingCache);
                }
                height += holder.itemView.getMeasuredHeight();
            }

            bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);
            Canvas bigCanvas = new Canvas(bigBitmap);
            Drawable lBackground = view.getBackground();
            if (lBackground instanceof ColorDrawable) {
                ColorDrawable lColorDrawable = (ColorDrawable) lBackground;
                int lColor = lColorDrawable.getColor();
                bigCanvas.drawColor(lColor);
            }

            for (int i = 0; i < size; i++) {
                Bitmap bitmap = bitmaCache.get(String.valueOf(i));
                bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);
                iHeight += bitmap.getHeight();
                bitmap.recycle();
            }
        }
        return bigBitmap;
    }

    public static Bitmap shotScrollView(ScrollView view) {
        int height = 0;
        //理论上scrollView只会有一个子View啦
        for (int i = 0; i < view.getChildCount(); i++) {
            height += view.getChildAt(i).getHeight();
        }
        //创建保存缓存的bitmap
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), height, Bitmap.Config.RGB_565);
        //可以简单的把Canvas理解为一个画板 而bitmap就是块画布
        Canvas canvas = new Canvas(bitmap);
        //获取ScrollView的背景颜色
        Drawable background = view.getBackground();
        //画出ScrollView的背景色 这里只用了color一种 有需要也可以自己扩展 也可以自己直接指定一种背景色
        if (background instanceof ColorDrawable) {
            ColorDrawable colorDrawable = (ColorDrawable) background;
            int color = colorDrawable.getColor();
            canvas.drawColor(color);
        }
        //把view的内容都画到指定的画板Canvas上
        view.draw(canvas);
        return bitmap;
    }
}
